package com.example.customview.horizontalview

import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.VelocityTracker
import android.view.ViewGroup
import android.widget.Scroller
import kotlin.math.abs

class HorizontalView @JvmOverloads constructor(
    context: Context, attributeSet: AttributeSet? = null,
    defaultStyle: Int = 0

) : ViewGroup(context, attributeSet, defaultStyle) {
    private var lastInterceptorX: Float = 0f
    private var lastInterceptorY: Float = 0f
    private var lastX: Float = 0f
    private var lastY: Float = 0f

    private var currentIndex: Int = 0
    private var childWidth: Int = 0
    private var scroller: Scroller? = null

    private var tracker: VelocityTracker? = null

    init {
        scroller = Scroller(context)
        tracker = VelocityTracker.obtain()

    }


    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val widthMode: Int = MeasureSpec.getMode(widthMeasureSpec)
        val widthSize: Int = MeasureSpec.getSize(widthMeasureSpec)

        val heightMode: Int = MeasureSpec.getMode(heightMeasureSpec)
        val heightSize: Int = MeasureSpec.getSize(heightMeasureSpec)

        measureChildren(widthMeasureSpec, heightMeasureSpec)

        if (childCount == 0) {
            setMeasuredDimension(0, 0)
        } else if (widthMode == MeasureSpec.AT_MOST && heightMode == MeasureSpec.AT_MOST) {
            val childAt = getChildAt(0)
            val measuredHeight = childAt.measuredHeight
            val measuredWidth = childAt.measuredWidth
            setMeasuredDimension(measuredWidth * childCount, measuredHeight)
        } else if (widthMode == MeasureSpec.AT_MOST) {
            val measuredWidth = getChildAt(0).measuredWidth
            setMeasuredDimension(measuredWidth * childCount, heightSize)
        } else if (heightMode == MeasureSpec.AT_MOST) {
            val measuredHeight = getChildAt(0).measuredHeight
            setMeasuredDimension(widthSize, measuredHeight)
        }


    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        var left: Int = 0
        for (i in 0 until childCount) {
            val view = getChildAt(i)
            if (view.visibility != GONE) {
                val width = view.measuredWidth
                childWidth = width
                view.layout(left, 0, left + width, view.measuredHeight)
                left += width
            }
        }
    }


    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        var interceptor: Boolean = false
        val x = ev.x
        val y = ev.y
        when (ev.action) {
            MotionEvent.ACTION_DOWN -> {
               interceptor = false
                if (scroller?.isFinished == false){
                    scroller?.abortAnimation()
                }
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaX = x - lastInterceptorX;
                val deltaY = y - lastInterceptorY
                if (abs(deltaX) - abs(deltaY) > 0) {
                    interceptor = true
                }else{
                    interceptor =false
                }

            }

            MotionEvent.ACTION_UP -> {
               interceptor = false
            }


        }
        lastX = x
        lastY = y
        lastInterceptorX = x
        lastInterceptorY = y
        return interceptor
    }


    //弹性滑动处理
    override fun onTouchEvent(event: MotionEvent): Boolean {
        var x = event.x
        var y = event.y
        when (event.action) {
            MotionEvent.ACTION_DOWN -> {
                if (scroller?.isFinished == false){
                    scroller?.abortAnimation()
                }
            }

            MotionEvent.ACTION_MOVE -> {
                val deltaX = x - lastX
                scrollBy(-deltaX.toInt(), 0)
            }

            MotionEvent.ACTION_UP -> {
                val distance = scrollX - currentIndex * childWidth
                if (abs(distance) > childWidth / 3) {
                    if (distance > 0) {
                        currentIndex++

                    } else {
                        currentIndex--

                    }

                }else{
                    tracker?.computeCurrentVelocity(1000)
                    val xV = tracker?.xVelocity
                   xV?.let {
                       if (abs(it)>50){
                          if (it>0){
                              currentIndex--
                          }else{
                              currentIndex++
                          }
                       }
                   }

                }
                if (currentIndex<0){
                    currentIndex = 0
                }else if (currentIndex>childCount-1){
                    currentIndex = childCount -1
                }
                smoothScrollTo(currentIndex * childWidth, 0)
                tracker?.clear()
            }

        }
        lastX = x
        lastY = y
        return true
    }

    private fun smoothScrollTo(destX: Int, destY: Int) {
        scroller?.let {
            it.startScroll(scrollX, scrollY, destX - scrollX, destY - scrollY, 1000)
            invalidate()
        }
    }

    override fun computeScroll() {
        super.computeScroll()
        if (scroller?.computeScrollOffset() == true) {
            scrollTo(scroller!!.currX, scroller!!.currY)
            postInvalidate()
        }
    }
}